java中map修改 java修改map的key

您所在的位置:网站首页 java 修改map中的value java中map修改 java修改map的key

java中map修改 java修改map的key

#java中map修改 java修改map的key| 来源: 网络整理| 查看: 265

首先给出经验:通常情况下都是将Map的key设为不可变量,如string等,不要用可变量做key。

以下是我的教训!

import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; public class TestMap { public static void main(String[] args) { List key1 = new LinkedList(); key1.add(1); Set value1 = new HashSet(); value1.add(100); //分别用List和Set做key和value Map map = new HashMap(); map.put(key1, value1); System.out.println(map.get(key1));//① key1.add(2); System.out.println(key1);//② Set coll = map.get(key1);//③ coll.remove(100); } }

在①处能够正常取得value1,输出[100];在②处修改了key1,key1变为[1,2],再次取value1,发现coll为null。经调试,确定map中的内容是{[1, 2]=[100]},为什么取不到东西呢?

看源码:

map的get方法源码如下:

public V get(Object key) { Node e; return (e = getNode(hash(key), key)) == null ? null : e.value; }

该方法首先调用了hash(key)方法。

hash(key)的源码如下:

static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }

因为在这里key的实际类型为LinkedList,在我的这个1.8版本的JDK中,LinkedList源码没有重写quals方法和hashCode方法,一直往回推,可以看到其祖先类AbstractList中重写了quals方法和hashCode方法,其中hashCode方法源码如下:

public int hashCode() { int hashCode = 1; for (E e : this) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); return hashCode; }

debug到这里会发现确实得到了一个哈希码,于是hash(key)也就返回了一个int值。接着回到get方法,在里面调用了getNode方法,源码如下:

final Node getNode(int hash, Object key) { Node[] tab; Node first, e; int n; K k; if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null && key.equals(k)))) return first; if ((e = first.next) != null) { if (first instanceof TreeNode) return ((TreeNode)first).getTreeNode(hash, key); do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } while ((e = e.next) != null); } } return null; }

debug到这里,发现不满足if的判断条件,因此返回了null。这个方法到底用了什么策略我不想去深究。

按常理,理应能够取得value的,这里却得到null,可能JDK设计人员有特殊的考虑吧,所以千万不要用可变量做键值啊!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3